home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Libraries / GUSI-RPC 4.0 / rpc_prot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-17  |  7.5 KB  |  309 lines  |  [TEXT/MPS ]

  1. /* @(#)rpc_prot.c    2.3 88/08/07 4.0 RPCSRC */
  2. /*
  3.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  4.  * unrestricted use provided that this legend is included on all tape
  5.  * media and as a part of the software program in whole or part.  Users
  6.  * may copy or modify Sun RPC without charge, but are not authorized
  7.  * to license or distribute it to anyone else except as part of a product or
  8.  * program developed by the user.
  9.  * 
  10.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  11.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  12.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  13.  * 
  14.  * Sun RPC is provided with no support and without any obligation on the
  15.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  16.  * modification or enhancement.
  17.  * 
  18.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  19.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  20.  * OR ANY PART THEREOF.
  21.  * 
  22.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  23.  * or profits or other special, indirect and consequential damages, even if
  24.  * Sun has been advised of the possibility of such damages.
  25.  * 
  26.  * Sun Microsystems, Inc.
  27.  * 2550 Garcia Avenue
  28.  * Mountain View, California  94043
  29.  */
  30. #if !defined(lint) && defined(SCCSIDS)
  31. static char sccsid[] = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";
  32. #endif
  33.  
  34. /*
  35.  * rpc_prot.c
  36.  *
  37.  * Copyright (C) 1984, Sun Microsystems, Inc.
  38.  *
  39.  * This set of routines implements the rpc message definition,
  40.  * its serializer and some common rpc utility routines.
  41.  * The routines are meant for various implementations of rpc -
  42.  * they are NOT for the rpc client or rpc service implementations!
  43.  * Because authentication stuff is easy and is part of rpc, the opaque
  44.  * routines are also in this program.
  45.  */
  46.  
  47. #if 0
  48. #include <sys/param.h>
  49. #endif
  50. #include <rpc/rpc.h>
  51.  
  52. /* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
  53.  
  54. struct opaque_auth _null_auth;
  55.  
  56. /*
  57.  * XDR an opaque authentication struct
  58.  * (see auth.h)
  59.  */
  60. bool_t
  61. xdr_opaque_auth(xdrs, ap)
  62.     register XDR *xdrs;
  63.     register struct opaque_auth *ap;
  64. {
  65.  
  66.     if (xdr_enum(xdrs, &(ap->oa_flavor)))
  67.         return (xdr_bytes(xdrs, &ap->oa_base,
  68.             &ap->oa_length, MAX_AUTH_BYTES));
  69.     return (FALSE);
  70. }
  71.  
  72. /*
  73.  * XDR a DES block
  74.  */
  75. bool_t
  76. xdr_des_block(xdrs, blkp)
  77.     register XDR *xdrs;
  78.     register des_block *blkp;
  79. {
  80.     return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block)));
  81. }
  82.  
  83. /* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
  84.  
  85. /*
  86.  * XDR the MSG_ACCEPTED part of a reply message union
  87.  */
  88. bool_t 
  89. xdr_accepted_reply(xdrs, ar)
  90.     register XDR *xdrs;   
  91.     register struct accepted_reply *ar;
  92. {
  93.  
  94.     /* personalized union, rather than calling xdr_union */
  95.     if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
  96.         return (FALSE);
  97.     if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat)))
  98.         return (FALSE);
  99.     switch (ar->ar_stat) {
  100.  
  101.     case SUCCESS:
  102.         return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where));
  103.  
  104.     case PROG_MISMATCH:
  105.         if (! xdr_u_long(xdrs, &(ar->ar_vers.low)))
  106.             return (FALSE);
  107.         return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
  108.     }
  109.     return (TRUE);  /* TRUE => open ended set of problems */
  110. }
  111.  
  112. /*
  113.  * XDR the MSG_DENIED part of a reply message union
  114.  */
  115. bool_t 
  116. xdr_rejected_reply(xdrs, rr)
  117.     register XDR *xdrs;
  118.     register struct rejected_reply *rr;
  119. {
  120.  
  121.     /* personalized union, rather than calling xdr_union */
  122.     if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat)))
  123.         return (FALSE);
  124.     switch (rr->rj_stat) {
  125.  
  126.     case RPC_MISMATCH:
  127.         if (! xdr_u_long(xdrs, &(rr->rj_vers.low)))
  128.             return (FALSE);
  129.         return (xdr_u_long(xdrs, &(rr->rj_vers.high)));
  130.  
  131.     case AUTH_ERROR:
  132.         return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why)));
  133.     }
  134.     return (FALSE);
  135. }
  136.  
  137. static struct xdr_discrim reply_dscrm[3] = {
  138.     { (int)MSG_ACCEPTED, xdr_accepted_reply },
  139.     { (int)MSG_DENIED, xdr_rejected_reply },
  140.     { __dontcare__, NULL_xdrproc_t } };
  141.  
  142. /*
  143.  * XDR a reply message
  144.  */
  145. bool_t
  146. xdr_replymsg(xdrs, rmsg)
  147.     register XDR *xdrs;
  148.     register struct rpc_msg *rmsg;
  149. {
  150.     if (
  151.         xdr_u_long(xdrs, &(rmsg->rm_xid)) && 
  152.         xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) &&
  153.         (rmsg->rm_direction == REPLY) )
  154.         return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
  155.            (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t));
  156.     return (FALSE);
  157. }
  158.  
  159.  
  160. /*
  161.  * Serializes the "static part" of a call message header.
  162.  * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
  163.  * The rm_xid is not really static, but the user can easily munge on the fly.
  164.  */
  165. bool_t
  166. xdr_callhdr(xdrs, cmsg)
  167.     register XDR *xdrs;
  168.     register struct rpc_msg *cmsg;
  169. {
  170.  
  171.     cmsg->rm_direction = CALL;
  172.     cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
  173.     if (xdrs->x_op == XDR_ENCODE) {
  174.         if (!xdr_u_long (xdrs, &(cmsg->rm_xid))) {
  175.             return FALSE;
  176.         }
  177.         if (!xdr_enum (xdrs, (enum_t *) &(cmsg->rm_direction))) {
  178.             return FALSE;
  179.         }
  180.         if (!xdr_u_long (xdrs, &(cmsg->rm_call.cb_rpcvers))) {
  181.             return FALSE;
  182.         }
  183.         if (!xdr_u_long (xdrs, &(cmsg->rm_call.cb_prog))) {
  184.             return FALSE;
  185.         }
  186.         if (!xdr_u_long (xdrs, &(cmsg->rm_call.cb_vers))) {
  187.             return FALSE;
  188.         }
  189.         return TRUE;
  190. #if 0
  191.         xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
  192.         xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
  193.         xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
  194.         xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) )
  195.         return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)));
  196. #endif
  197.     }
  198.     return (FALSE);
  199. }
  200.  
  201. /* ************************** Client utility routine ************* */
  202.  
  203. static void
  204. accepted(acpt_stat, error)
  205.     register enum accept_stat acpt_stat;
  206.     register struct rpc_err *error;
  207. {
  208.  
  209.     switch (acpt_stat) {
  210.  
  211.     case PROG_UNAVAIL:
  212.         error->re_status = RPC_PROGUNAVAIL;
  213.         return;
  214.  
  215.     case PROG_MISMATCH:
  216.         error->re_status = RPC_PROGVERSMISMATCH;
  217.         return;
  218.  
  219.     case PROC_UNAVAIL:
  220.         error->re_status = RPC_PROCUNAVAIL;
  221.         return;
  222.  
  223.     case GARBAGE_ARGS:
  224.         error->re_status = RPC_CANTDECODEARGS;
  225.         return;
  226.  
  227.     case SYSTEM_ERR:
  228.         error->re_status = RPC_SYSTEMERROR;
  229.         return;
  230.  
  231.     case SUCCESS:
  232.         error->re_status = RPC_SUCCESS;
  233.         return;
  234.     }
  235.     /* something's wrong, but we don't know what ... */
  236.     error->re_status = RPC_FAILED;
  237.     error->re_lb.s1 = (long)MSG_ACCEPTED;
  238.     error->re_lb.s2 = (long)acpt_stat;
  239. }
  240.  
  241. static void 
  242. rejected(rjct_stat, error)
  243.     register enum reject_stat rjct_stat;
  244.     register struct rpc_err *error;
  245. {
  246.  
  247.     switch (rjct_stat) {
  248.  
  249.     case RPC_VERSMISMATCH:
  250.         error->re_status = RPC_VERSMISMATCH;
  251.         return;
  252.  
  253.     case AUTH_ERROR:
  254.         error->re_status = RPC_AUTHERROR;
  255.         return;
  256.     }
  257.     /* something's wrong, but we don't know what ... */
  258.     error->re_status = RPC_FAILED;
  259.     error->re_lb.s1 = (long)MSG_DENIED;
  260.     error->re_lb.s2 = (long)rjct_stat;
  261. }
  262.  
  263. /*
  264.  * given a reply message, fills in the error
  265.  */
  266. void
  267. _seterr_reply(msg, error)
  268.     register struct rpc_msg *msg;
  269.     register struct rpc_err *error;
  270. {
  271.  
  272.     /* optimized for normal, SUCCESSful case */
  273.     switch (msg->rm_reply.rp_stat) {
  274.  
  275.     case MSG_ACCEPTED:
  276.         if (msg->acpted_rply.ar_stat == SUCCESS) {
  277.             error->re_status = RPC_SUCCESS;
  278.             return;
  279.         };
  280.         accepted(msg->acpted_rply.ar_stat, error);
  281.         break;
  282.  
  283.     case MSG_DENIED:
  284.         rejected(msg->rjcted_rply.rj_stat, error);
  285.         break;
  286.  
  287.     default:
  288.         error->re_status = RPC_FAILED;
  289.         error->re_lb.s1 = (long)(msg->rm_reply.rp_stat);
  290.         break;
  291.     }
  292.     switch (error->re_status) {
  293.  
  294.     case RPC_VERSMISMATCH:
  295.         error->re_vers.low = msg->rjcted_rply.rj_vers.low;
  296.         error->re_vers.high = msg->rjcted_rply.rj_vers.high;
  297.         break;
  298.  
  299.     case RPC_AUTHERROR:
  300.         error->re_why = msg->rjcted_rply.rj_why;
  301.         break;
  302.  
  303.     case RPC_PROGVERSMISMATCH:
  304.         error->re_vers.low = msg->acpted_rply.ar_vers.low;
  305.         error->re_vers.high = msg->acpted_rply.ar_vers.high;
  306.         break;
  307.     }
  308. }
  309.